//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package io.lumine.xikage.mythicmobs.adapters.bukkit.listeners;

import io.lumine.xikage.mythicmobs.MythicMobs;
import io.lumine.xikage.mythicmobs.PluginComponent;
import io.lumine.xikage.mythicmobs.adapters.AbstractEntity;
import io.lumine.xikage.mythicmobs.adapters.AbstractWorld;
import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitAdapter;
import io.lumine.xikage.mythicmobs.adapters.bukkit.BukkitEntityType;
import io.lumine.xikage.mythicmobs.adapters.bukkit.entities.*;
import io.lumine.xikage.mythicmobs.compatibility.WorldGuardSupport;
import io.lumine.xikage.mythicmobs.io.ConfigManager;
import io.lumine.xikage.mythicmobs.logging.MythicLogger;
import io.lumine.xikage.mythicmobs.logging.MythicLogger.DebugLevel;
import io.lumine.xikage.mythicmobs.mobs.ActiveMob;
import io.lumine.xikage.mythicmobs.mobs.MobManager;
import io.lumine.xikage.mythicmobs.mobs.MythicMob;
import io.lumine.xikage.mythicmobs.mobs.WorldScaling;
import io.lumine.xikage.mythicmobs.mobs.entities.MythicEntityType;
import io.lumine.xikage.mythicmobs.skills.SkillTrigger;
import io.lumine.xikage.mythicmobs.skills.TriggeredSkill;
import io.lumine.xikage.mythicmobs.spawning.random.RandomSpawnPoint;
import io.lumine.xikage.mythicmobs.utils.Events;
import io.lumine.xikage.mythicmobs.utils.Schedulers;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.entity.Damageable;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Projectile;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.block.EntityBlockFormEvent;
import org.bukkit.event.entity.*;
import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason;
import org.bukkit.event.player.PlayerArmorStandManipulateEvent;
import org.bukkit.event.player.PlayerInteractEntityEvent;
import org.bukkit.event.world.ChunkLoadEvent;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.potion.PotionEffect;
import org.bukkit.projectiles.ProjectileSource;

import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;

public class MobListeners extends PluginComponent implements Listener {
    public MobListeners(MythicMobs plugin) {
        super(plugin);
    }

    public void load(MythicMobs plugin) {
        Bukkit.getPluginManager().registerEvents(this, plugin);
        Events.subscribe(PlayerArmorStandManipulateEvent.class).handler((event) -> {
            MythicLogger.debug(DebugLevel.EVENT, "PlayerArmorStandManipulateEvent fired", new Object[0]);
            Optional<ActiveMob> maybeMob = this.getPlugin().getMobManager().getActiveMob(event.getRightClicked().getUniqueId());
            if (maybeMob.isPresent()) {
                ActiveMob am = (ActiveMob)maybeMob.get();
                if (!am.getType().getIsInteractable()) {
                    event.setCancelled(true);
                }
            }

        }).bindWith(this);
        Events.subscribe(SlimeSplitEvent.class, EventPriority.HIGH).handler((event) -> {
            MythicLogger.debug(DebugLevel.EVENT, "SlimeSplitEvent fired", new Object[0]);
            Optional<ActiveMob> maybeMob = this.getPlugin().getMobManager().getActiveMob(event.getEntity().getUniqueId());
            if (maybeMob.isPresent()) {
                BukkitEntityType mythicEntity = ((ActiveMob)maybeMob.get()).getType().getMythicEntity();
                if (mythicEntity instanceof BukkitSlime) {
                    if (!((BukkitSlime)mythicEntity).canSplit()) {
                        event.setCount(0);
                        event.setCancelled(true);
                    }
                } else if (mythicEntity instanceof BukkitMagmaCube && !((BukkitMagmaCube)mythicEntity).canSplit()) {
                    event.setCount(0);
                    event.setCancelled(true);
                }
            }

        }).bindWith(this);
        Events.subscribe(CreatureSpawnEvent.class, EventPriority.HIGHEST).handler((event) -> {
            if (!ConfigManager.debugMode) {
                if (!ConfigManager.debugSpawners) {
                    if (!this.getPlugin().getCompatibility().getWorldGuard().isPresent() || ((WorldGuardSupport)this.getPlugin().getCompatibility().getWorldGuard().get()).LocationAllowsMobSpawning(event.getLocation())) {
                        MythicLogger.debug(DebugLevel.EVENT, "CreatureSpawnEvent fired", new Object[0]);
                        AbstractEntity spawn = BukkitAdapter.adapt(event.getEntity());
                        if (event.getSpawnReason() != SpawnReason.NATURAL && event.getSpawnReason() != SpawnReason.CHUNK_GEN) {
                            if (event.getSpawnReason() == SpawnReason.JOCKEY) {
                                List<Entity> passengers = event.getEntity().getPassengers();
                                if (!passengers.isEmpty()) {
                                    MobManager mm = this.getPlugin().getMobManager();
                                    if (mm.isActiveMob(((Entity)passengers.get(0)).getUniqueId()) && !mm.isActiveMob(event.getEntity().getUniqueId()) && mm.getMythicMobInstance((Entity)passengers.get(0)).getType().getPreventJockeyMounts()) {
                                        event.setCancelled(true);
                                        return;
                                    }
                                }
                            }
                        } else {
                            if (ConfigManager.isVanillaSpawnsDisabled() && !BukkitEntityType.getIsSpawning()) {
                                event.setCancelled(true);
                            }

                            int mobsInChunk = 0;

                            try {
                                AbstractWorld world = spawn.getLocation().getWorld();
                                int x = spawn.getLocation().getBlockX() >> 4;
                                int z = spawn.getLocation().getBlockZ() >> 4;
                                mobsInChunk = world.getEntitiesInChunk(x, z);
                                MythicLogger.debug(DebugLevel.EVENT, "| Mobs in chunk calculated to be {0}", new Object[]{mobsInChunk});
                            } catch (Exception var10) {
                                var10.printStackTrace();
                            }

                            if (mobsInChunk >= ConfigManager.getRSMaxMobsPerChunk()) {
                                MythicLogger.debug(DebugLevel.EVENT, "! Too many entities in chunk, cancelling", new Object[0]);
                                event.setCancelled(true);
                                return;
                            }
                        }

                        RandomSpawnPoint rsp = new RandomSpawnPoint(BukkitAdapter.adapt(event.getEntity()), BukkitAdapter.adapt(event.getLocation()), event.getSpawnReason());
                        Entity ee = BukkitAdapter.adapt(this.getPlugin().getRandomSpawningManager().handleSpawnEvent(rsp));
                        if (ee != null) {
                            event.setCancelled(true);
                        } else if (event.getSpawnReason() != SpawnReason.BREEDING && !BukkitEntityType.getIsSpawning()) {
                            MythicEntityType met = this.getPlugin().server().getMythicEntityType(event.getEntity());
                            Optional<MythicMob> maybeType = this.getPlugin().getMobManager().getVanillaType(met);
                            if (maybeType.isPresent()) {
                                MythicMob mmx = (MythicMob)maybeType.get();
                                int level = 1 + WorldScaling.getLevelBonus(spawn.getLocation());
                                ActiveMob am = this.getPlugin().getMobManager().registerActiveMob(spawn, mmx, level);
                                mmx.getMythicEntity().applyOptions(event.getEntity());
                                mmx.applyMobOptions(am, (double)level);
                                mmx.applyMobVolatileOptions(am);
                                mmx.applySpawnModifiers(am);
                            }
                        }

                        if (event.getSpawnReason() == SpawnReason.CUSTOM) {
                            LivingEntity l;
                            if (ConfigManager.UseCompatibilityMode) {
                                l = event.getEntity();
                                Schedulers.sync().runLater(() -> {
                                    if (!this.getPlugin().getMobManager().isActiveMob(spawn.getUniqueId())) {
                                        MythicLogger.debug(DebugLevel.INFO, "Compatibility mode enabled and found custom mob spawn! Checking for MythicMob '" + l.getCustomName() + "'...", new Object[0]);
                                        MythicMob mm = this.getPlugin().getMobManager().getMythicMobByDisplayCompat(spawn);
                                        if (mm != null) {
                                            this.getPlugin().getMobManager().SetupMythicMobCompat(l, mm);
                                        } else {
                                            this.getPlugin().getMobManager().setIgnoreEntity(l.getUniqueId());
                                        }
                                    }

                                }, 10L);
                            } else {
                                l = event.getEntity();
                                Schedulers.sync().runLater(() -> {
                                    if (!this.getPlugin().getMobManager().isActiveMob(l.getUniqueId())) {
                                        this.getPlugin().getMobManager().setIgnoreEntity(l.getUniqueId());
                                    }

                                }, 20L);
                            }
                        }

                    }
                }
            }
        }).bindWith(this);
        Events.subscribe(ChunkLoadEvent.class, EventPriority.HIGHEST).filter((event) -> {
            return event.isNewChunk();
        }).handler((event) -> {
            if (!ConfigManager.debugMode) {
                if (!ConfigManager.debugSpawners) {
                    MythicLogger.debug(DebugLevel.EVENT, "ChunkLoadEvent (New Chunk) fired", new Object[0]);
                    Entity[] var2 = event.getChunk().getEntities();
                    int var3 = var2.length;

                    for(int var4 = 0; var4 < var3; ++var4) {
                        Entity entity = var2[var4];
                        if (this.getPlugin().getCompatibility().getWorldGuard().isPresent() && !((WorldGuardSupport)this.getPlugin().getCompatibility().getWorldGuard().get()).LocationAllowsMobSpawning(entity.getLocation())) {
                            entity.remove();
                        } else {
                            AbstractEntity spawn = BukkitAdapter.adapt(entity);
                            RandomSpawnPoint rsp = new RandomSpawnPoint(spawn, spawn.getLocation(), SpawnReason.NATURAL);
                            Entity ee = BukkitAdapter.adapt(this.getPlugin().getRandomSpawningManager().handleSpawnEvent(rsp));
                            if (ee != null) {
                                entity.remove();
                            } else if (ConfigManager.isVanillaSpawnsDisabled() && !BukkitEntityType.getIsSpawning()) {
                                entity.remove();
                            }
                        }
                    }

                }
            }
        }).bindWith(this);
    }

    public void unload() {
    }

    @EventHandler(
            priority = EventPriority.LOWEST,
            ignoreCancelled = true
    )
    public void damagePassthroughEvent(EntityDamageEvent event) {
        if (event.getEntity() instanceof Damageable) {
            Damageable damaged = (Damageable)event.getEntity();
            if (this.getPlugin().getMobManager().isActiveMob(damaged.getUniqueId())) {
                ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(damaged);
                if (am.getType().getPassthroughDamage() && am.getParent() != null) {
                    MythicLogger.debug(DebugLevel.TRIGGER, "Passing damage to parent", new Object[0]);
                    event.setCancelled(true);
                    LivingEntity parent = (LivingEntity)am.getParent().getEntity().getBukkitEntity();
                    if (event instanceof EntityDamageByEntityEvent) {
                        EntityDamageByEntityEvent ee = (EntityDamageByEntityEvent)event;
                        Entity damager = ee.getDamager();
                        if (damager instanceof Projectile) {
                            MythicLogger.debug(DebugLevel.INFO, "Damage passed from arrow", new Object[0]);
                            ProjectileSource shooter = ((Projectile)damager).getShooter();
                            if (shooter instanceof LivingEntity) {
                                parent.damage(ee.getDamage(), (Entity)((Projectile)damager).getShooter());
                            } else {
                                parent.damage(event.getDamage());
                            }

                            damager.remove();
                        } else {
                            parent.damage(ee.getDamage(), damager);
                        }
                    } else {
                        parent.damage(event.getDamage());
                    }

                }
            }
        }
    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onMobTame(EntityTameEvent event) {
        Entity e = event.getEntity();
        if (this.getPlugin().getMobManager().isActiveMob(e.getUniqueId())) {
            ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(e);
            Schedulers.sync().runLater(() -> {
                am.getType().applyMobOptions(am, am.getLevel());
                am.getType().applyMobVolatileOptions(am);
            }, 5L);
        }

    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void TagEntity(PlayerInteractEntityEvent e) {
        if (e.getRightClicked() instanceof LivingEntity) {
            LivingEntity l = (LivingEntity)e.getRightClicked();
            if (this.getPlugin().getMobManager().isActiveMob(l.getUniqueId())) {
                EntityEquipment ee = e.getPlayer().getEquipment();
                if (ee == null || ee.getItemInMainHand().getType() == Material.NAME_TAG) {
                    if (this.getPlugin().getMobManager().getMythicMobInstance(l).getType().getPreventRename()) {
                        e.setCancelled(true);
                        e.getPlayer().sendMessage("§cThis mob can't be renamed");
                    }

                }
            }
        }
    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onCombust(EntityCombustEvent event) {
        if (!(event instanceof EntityCombustByEntityEvent) && !(event instanceof EntityCombustByBlockEvent)) {
            World world = event.getEntity().getWorld();
            if (world.getEnvironment() == Environment.NORMAL) {
                Entity entity = event.getEntity();
                if (this.getPlugin().getMobManager().isActiveMob(entity.getUniqueId())) {
                    ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(entity);
                    if (am.getType().getPreventSunburn()) {
                        event.setCancelled(true);
                    }
                }

            }
        }
    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onTameEntity(PlayerInteractEntityEvent e) {
        if (e.getRightClicked() instanceof LivingEntity) {
            if (e.getPlayer().getItemInHand().getType() == Material.BONE) {
                LivingEntity l = (LivingEntity)e.getRightClicked();
                if (this.getPlugin().getMobManager().isActiveMob(l.getUniqueId())) {
                    ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(l);
                    if (am.getType().getMythicEntity() instanceof BukkitWolf && !((BukkitWolf)am.getType().getMythicEntity()).isTameable()) {
                        e.setCancelled(true);
                        e.getPlayer().sendMessage(ChatColor.RED + "That mob can't be tamed!");
                    }

                }
            }
        }
    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onLeashEntity(PlayerLeashEntityEvent e) {
        if (e.getEntity() instanceof LivingEntity) {
            LivingEntity l = (LivingEntity)e.getEntity();
            if (this.getPlugin().getMobManager().isActiveMob(l.getUniqueId())) {
                ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(l);
                if (am.getType().getPreventLeashing()) {
                    e.setCancelled(true);
                    e.getPlayer().sendMessage(ChatColor.RED + "That mob can't be leashed!");
                }

            }
        }
    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onBlockForm(EntityBlockFormEvent e) {
        if (this.getPlugin().getMobManager().isActiveMob(e.getEntity().getUniqueId())) {
            ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(e.getEntity());
            if (am.getType().getMythicEntity() instanceof BukkitSnowman && ((BukkitSnowman)am.getType().getMythicEntity()).getPreventSnowFormation()) {
                e.setCancelled(true);
            }
        }

    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onTeleportEvent(EntityTeleportEvent e) {
        if (e.getEntity() instanceof LivingEntity) {
            ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(e.getEntity());
            if (am != null) {
                if (am.getType().getPreventEndermanTeleport()) {
                    e.getEntity().teleport(e.getFrom());
                    e.setCancelled(true);
                } else {
                    TriggeredSkill ts = new TriggeredSkill(SkillTrigger.TELEPORT, am, (AbstractEntity)null);
                    if (ts.getCancelled()) {
                        e.setCancelled(true);
                    }
                }

            }
        }
    }

    @EventHandler(
            priority = EventPriority.HIGH
    )
    public void onChangeBlockEvent(EntityChangeBlockEvent e) {
        if (this.getPlugin().getMobManager().isActiveMob(e.getEntity().getUniqueId())) {
            ActiveMob am = this.getPlugin().getMobManager().getMythicMobInstance(e.getEntity());
            if (am.getType().getMythicEntity() instanceof BukkitSilverfish && ((BukkitSilverfish)am.getType().getMythicEntity()).getPreventBlockInfection()) {
                e.setCancelled(true);
                LivingEntity l = (LivingEntity)e.getEntity();
                ActiveMob amN = am.getType().spawn(am.getEntity().getLocation(), am.getLevel(), io.lumine.xikage.mythicmobs.mobs.entities.SpawnReason.OTHER);
                LivingEntity ll = (LivingEntity)BukkitAdapter.adapt(amN.getEntity());
                ll.setMaxHealth(l.getMaxHealth());
                ll.setHealth(l.getHealth());
                if (l.getPassenger() != null) {
                    ll.setPassenger(l.getPassenger());
                }

                if (l.getVehicle() != null) {
                    l.getVehicle().setPassenger(ll);
                }

                Collection<PotionEffect> pe = l.getActivePotionEffects();
                Iterator var7 = pe.iterator();

                while(var7.hasNext()) {
                    PotionEffect p = (PotionEffect)var7.next();
                    ll.addPotionEffect(p);
                }

                ActiveMob am2 = this.getPlugin().getMobManager().getMythicMobInstance(BukkitAdapter.adapt(ll));
                if (am2 == null) {
                    MythicLogger.debug(DebugLevel.INFO, "-- Something prevented Silverfish from respawning! PreventBlockInfection failed :(", new Object[0]);
                    return;
                }

                am2.setStance(am.getStance());
                am2.importPlayerKills(am.getPlayerKills());
                am2.importThreatTable(am.getThreatTable());
                l.remove();
                am.setDead();
            }
        }

    }
}
